package com.glink.manage.common;

import cn.hutool.core.date.DateUtil;
import com.glink.common.contants.BaseConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.manage.common.sm.Sm2Encryption;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.util.Date;

/**
 * 检查软件授权
 * @author xum
 * @since 2025/2/17
 **/
@Slf4j
public class GrantCodeUtil {

    /**
     * 获取有效期
     * @param privateKey 私钥
     * @param grantCode 授权码
     * @param serialNumber 磁盘序列号
     * @return 有效期
     */
    public static Date periodValidity(String privateKey, String grantCode, String serialNumber) throws GeneralSimpleException {
        if(StringUtils.isBlank(privateKey)){
            throw new GeneralSimpleException("300013", "私钥不存在！");
        }
        if(StringUtils.isBlank(grantCode)){
            throw new GeneralSimpleException("300013", "授权码不存在！");
        }
        if(StringUtils.isBlank(serialNumber)){
            throw new GeneralSimpleException("300013", "序列号不存在！");
        }
        
        //检查授权码
        StringBuilder builder = new StringBuilder();
        String grantValue;
        try {
            grantValue = Sm2Encryption.decryptBase64(privateKey, grantCode);
        }catch (Exception e){
            log.error("授权码解密异常", e);
            throw new GeneralSimpleException("300013", "解密失败！");
        }
        String[] arr = grantValue.split(Constants.REGEX);
        if(arr.length != 4){
            throw new GeneralSimpleException("300013", "结构不完整！");
        }

        if(!StringUtils.equals(serialNumber, arr[0])){
            builder.append("设备序号错误！");
        }

        if(StringUtils.isBlank(arr[2])){
            builder.append("授权模块为空！");
        }
        
        if (builder.length() > 0) {
            throw new GeneralSimpleException("300013", builder.toString());
        }

        Date date = dateStrToDate(arr[3]);
        checkDateEfficacious(date, serialNumber);
        return date;
    }

    /**
     * 校验授权
     * @param privateKey 私钥
     * @param grantCode 授权码
     * @param serialNumber 磁盘序列号
     */
    public static void checkPeriodValidity(String privateKey, String grantCode, String serialNumber) throws GeneralSimpleException {
        if(StringUtils.isBlank(privateKey)){
            throw new GeneralSimpleException("300013", "私钥不存在！");
        }
        if(StringUtils.isBlank(grantCode)){
            throw new GeneralSimpleException("300013", "授权码不存在！");
        }
        if(StringUtils.isBlank(serialNumber)){
            throw new GeneralSimpleException("300013", "序列号不存在！");
        }

        //检查授权码
        StringBuilder builder = new StringBuilder();
        String grantValue;
        try {
            grantValue = Sm2Encryption.decryptBase64(privateKey, grantCode);
        }catch (Exception e){
            log.error("授权码解密异常", e);
            throw new GeneralSimpleException("300013", "解密失败！");
        }
        String[] arr = grantValue.split(Constants.REGEX);
        if(arr.length != 4){
            throw new GeneralSimpleException("300013", "结构不完整！");
        }

        if(!StringUtils.equals(serialNumber, arr[0])){
            builder.append("设备序号错误！");
        }

        if(StringUtils.isBlank(arr[2])){
            builder.append("授权模块为空！");
        }

        if (builder.length() > 0) {
            throw new GeneralSimpleException("300013", builder.toString());
        }

        Date date = dateStrToDate(arr[3]);
        if(System.currentTimeMillis() > date.getTime()){
            throw new GeneralSimpleException("300014", serialNumber);
        }
    }

    /**
     * 日期字符串格式化
     * @param dateStr 日期字符串
     * @return 日期对象
     */
    private static Date dateStrToDate(String dateStr) throws GeneralSimpleException {
        Date date = null;
        if(StringUtils.isBlank(dateStr)){
            throw new GeneralSimpleException("300013", "日期为空");
        }
        try {
            date = DateUtil.endOfDay(DateUtils.parseDate(dateStr, BaseConstants.DATE_FORMAT_SHORT_DATE_3));
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("授权码-授权日期格式化异常", e);
            throw new GeneralSimpleException("300013", "日期（" + dateStr + "）格式有误");
        }
        return date;
    }
    
    /**
     * 校验日期是否合格
     * @param date 日期
     */
    public static void checkDateEfficacious(Date date, String serialNumber) throws GeneralSimpleException {
        if(System.currentTimeMillis() > date.getTime()){
            throw new GeneralSimpleException("300014", serialNumber);
        }
    }
}
